﻿using System;
using System.Reflection;

namespace Casimeda.Framework.Dependency
{
    public interface IDependencyContainerRegister
    {
        /// <summary>
        /// Registers a new <c>type</c> to the container.
        /// </summary>
        /// <param name = "key">The name of the specified type.</param>
        /// <param name = "type">The type to register.</param>
        /// <param name = "instance">The instance of <paramref name = "type" />.</param>
        /// <param name = "lifeCycle">The life cycle.</param>
        /// <remarks>
        /// 	Singleton should be the default lifecycle.
        /// </remarks>
        void Register(string key, Type type, object instance, DependencyLifeCycle lifeCycle);

        /// <summary>
        /// Registers a new <c>type</c> to the container.
        /// </summary>
        /// <param name = "key">The name of the specified type.</param>
        /// <param name = "type">The type to register.</param>
        /// <param name = "implementedBy">The implementation of <paramref name = "type" />.</param>
        /// <param name = "lifeCycle">The life cycle.</param>
        /// <remarks>
        /// Singleton should be the default lifecycle.
        /// </remarks>
        void Register(string key, Type type, Type implementedBy, DependencyLifeCycle lifeCycle);

        /// <summary>
        /// Registers the specified key.
        /// </summary>
        /// <typeparam name = "T">The type to register</typeparam>
        /// <typeparam name = "TK">The implementation of the generic type <c>T</c>.</typeparam>
        /// <param name = "key">The name of the specified type.</param>
        /// <param name = "instance">The instance of the generic type<c>TK</c>.</param>
        /// <param name = "lifeCycle">The life cycle.</param>
        /// <remarks>
        /// Singleton should be the default lifecycle.
        /// </remarks>
        void Register<T, TK>(string key, TK instance, DependencyLifeCycle lifeCycle) where TK : class , T;

        /// <summary>
        /// Registers the specified key.
        /// </summary>
        /// <typeparam name = "T">The type to register</typeparam>
        /// <typeparam name = "TK">The implementation of the generic type <c>T</c>.</typeparam>
        /// <param name = "key">The name of the specified type.</param>
        /// <param name = "lifeCycle">The life cycle.</param>
        /// <remarks>
        /// Singleton should be the default lifecycle.
        /// </remarks>
        void Register<T, TK>(string key, DependencyLifeCycle lifeCycle) where TK : class , T;

        /// <summary>
        /// Registers the specified type <c>T</c> for all implmentation of <paramref name = "assembly" />.
        /// </summary>
        /// <typeparam name = "T">The type to register</typeparam>
        /// <param name = "assembly">The assembly.</param>
        /// <param name = "lifeCycle">The life cycle.</param>
        /// <remarks>
        /// Singleton should be the default lifecycle.
        /// </remarks>
        void RegisterComponentsByBaseClass<T>(Assembly assembly, DependencyLifeCycle lifeCycle);

        /// <summary>
        /// Registers a new <c>type</c> to the container.
        /// </summary>
        /// <param name = "key">The name of the specified type.</param>
        /// <param name = "type">The type to register.</param>
        /// <param name = "instance">The instance of <paramref name = "type" />.</param>
        /// <param name = "lifeCycle">The life cycle.</param>
        /// <remarks>
        /// Singleton should be the default lifecycle.
        /// </remarks>
        void AddRegistration(string key, Type type, object instance, DependencyLifeCycle lifeCycle);

        /// <summary>
        /// Registers a new <c>type</c> to the container.
        /// </summary>
        /// <param name = "key">The name of the specified type.</param>
        /// <param name = "type">The type to register.</param>
        /// <param name = "implementedBy">The implementation of <paramref name = "type" />.</param>
        /// <param name = "lifeCycle">The life cycle.</param>
        /// <remarks>
        /// Singleton should be the default lifecycle.
        /// </remarks>
        void AddRegistration(string key, Type type, Type implementedBy, DependencyLifeCycle lifeCycle);

        /// <summary>
        /// Registers the specified key.
        /// </summary>
        /// <typeparam name = "T">The type to register</typeparam>
        /// <typeparam name = "TK">The implementation of the generic type <c>T</c>.</typeparam>
        /// <param name = "key">The name of the specified type.</param>
        /// <param name = "instance">The instance of the generic type<c>TK</c>.</param>
        /// <param name = "lifeCycle">The life cycle.</param>
        /// <remarks>
        /// Singleton should be the default lifecycle.
        /// </remarks>
        void AddRegistration<T, TK>(string key, TK instance, DependencyLifeCycle lifeCycle) where TK : class , T;

        /// <summary>
        /// Registers the specified key.
        /// </summary>
        /// <typeparam name = "T">The type to register</typeparam>
        /// <typeparam name = "TK">The implementation of the generic type <c>T</c>.</typeparam>
        /// <param name = "key">The name of the specified type.</param>
        /// <param name = "lifeCycle">The life cycle.</param>
        /// <remarks>
        /// Singleton should be the default lifecycle.
        /// </remarks>
        void AddRegistration<T, TK>(string key, DependencyLifeCycle lifeCycle) where TK : class , T;

        /// <summary>
        /// Registers the specified type <c>T</c> for all implmentation of <paramref name = "assembly" />.
        /// </summary>
        /// <typeparam name = "T">The type to register</typeparam>
        /// <param name = "assembly">The assembly.</param>
        /// <param name = "lifeCycle">The life cycle.</param>
        /// <remarks>
        /// Singleton should be the default lifecycle.
        /// </remarks>
        void AddRegistrationComponentsByBaseClass<T>(Assembly assembly, DependencyLifeCycle lifeCycle);
    }
}
